#include <QDeclarativeItem>
#include <QGLWidget>
#include <QGLFormat>
#include <QUrl>
#include <QTimer>
#include <QApplication>
#include <QDeclarativeEngine>

#if defined(Q_WS_MAEMO_5)
// This is needed for Maemo5 to recognize minimization of the application window
#include <QtDBus>
#endif

#include "mainwidget.h"

QString filename(contentPath + "MainView.qml");
int SPLASH_SCREEN = 0;
int MENU_SCREEN = 1;
int GAME_SCREEN = 2;

MainWidget::MainWidget(QWidget *parent)
    : QDeclarativeView(parent),
      m_prevTime(0),
      m_currentTime(0),
      m_frameTime(0.0f),
      m_fps(0.0f),
      m_paused(true),
      m_timerId(0)
{
    // Switch to fullscreen in device
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
    setWindowState(Qt::WindowFullScreen);
#endif

    setResizeMode(QDeclarativeView::SizeRootObjectToView);

    // Setup context
    m_context = rootContext();
    m_context->setContextProperty("mainWidget", this);
    m_context->setContextProperty("gameData", &m_gameData);

    // Set view optimizations not already done for QDeclarativeView
    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_NoSystemBackground);

    // Make QDeclarativeView use OpenGL backend
    QGLWidget *glWidget = new QGLWidget(this);
    setViewport(glWidget);
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

    // Open root QML file
    setSource(QUrl(filename));

    create();
}

void MainWidget::create(){
//    QDeclarativeComponent *component = new QDeclarativeComponent(engine(), QUrl::fromLocalFile(contentPath + "MainMenu.qml"));
//    qDebug() << "eaaa";
//    myScreen = qobject_cast<Screen*>(component->create());
//    myScreen->setObjectName("huhu");
//    qDebug() << "eaaa";
//    myScreen->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
//    myScreen->setParent(qobject_cast<QObject*>(rootObject()));
    myScreen = new MenuWindow(engine());
    myScreen->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
    myScreen->setParent(qobject_cast<QObject*>(rootObject()));

    m_currentTime = getTickCount();
    m_prevTime = m_currentTime;
    m_fps = 0.0f;
    m_frameTime = 0.0f;

    prevScreen = 0;
    currScreen = 1;
    isHideScreen = false;
    isSoundMute =false;
    isMusicMute=false;
    resume();
//    myGameWindow = new GameWindow(0, engine());
//    myGameWindow->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
//    myGameWindow->setParent(qobject_cast<QObject*>(rootObject()));
//    myGameWindow->create();

//    QDeclarativeComponent *component2 = new QDeclarativeComponent(engine(), QUrl::fromLocalFile(contentPath + "Cake.qml"));
//    QDeclarativeItem *mycake = qobject_cast<QDeclarativeItem*>(component2->create());
//    mycake->setProperty("x", "200");
//    mycake->setProperty("y", "200");
//    mycake->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
//    mycake->setParent(qobject_cast<QObject*>(rootObject()));

//    myGameWindow = new GameWindow(0, engine());
//    myGameWindow->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
//    myGameWindow->create();

}

void MainWidget::update(float deltatime)
{
    if (isHideScreen){
        deleteScreen(prevScreen);
    }
    //qDebug() << getFPS();
    myScreen->update(deltatime);

}

void MainWidget::pause()
{
    if (m_paused)
        return;

    m_paused = true;
    killTimer(m_timerId);
    m_timerId = 0;
}

void MainWidget::resume()
{
    if (!m_paused)
        return;

    m_paused = false;
    m_timerId = startTimer(0);
}

unsigned int MainWidget::getTickCount() const
{
    QTime now = QTime::currentTime();
    return (now.hour() * 3600 + now.minute() * 60 + now.second()) * 1000
            + now.msec();
}

void MainWidget::setScreen(int i)
{
    switch (i)
    {
        case 1:
            myScreen = new MenuWindow(engine());
            myScreen->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
            myScreen->setParent(qobject_cast<QObject*>(rootObject()));

            prevScreen = currScreen;
            currScreen = 1;
            isHideScreen = true;
            break;

        case 2:
            myScreen = new LevelWindow(engine());
            myScreen->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
            myScreen->setParent(qobject_cast<QObject*>(rootObject()));

            prevScreen = currScreen;
            currScreen = 2;
            isHideScreen = true;
            break;

        case 3:
            myScreen = new InstructionView(engine());
            myScreen->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
            myScreen->setParent(qobject_cast<QObject*>(rootObject()));

            prevScreen = currScreen;
            currScreen = 3;
            isHideScreen = true;
            break;

        case 4:
            myScreen = new GameWindow(engine(),3);
            myScreen->setParentItem(qobject_cast<QDeclarativeItem*>(rootObject()));
            myScreen->setParent(qobject_cast<QObject*>(rootObject()));

            prevScreen = currScreen;
            currScreen = 3;
            isHideScreen = true;
            break;
    }
}

float MainWidget::getFrameTime() const
{
    return m_frameTime;
}

float MainWidget::getFPS() const
{
    return m_fps;
}

void MainWidget::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);
    render();
}

void MainWidget::render()
{
    m_prevTime = m_currentTime;
    m_currentTime = getTickCount();
//    qDebug() << m_currentTime;
    m_frameTime = (float)(m_currentTime - m_prevTime) * 0.001f;

    if (m_frameTime != 0.0f) {
        m_fps = 1.0f / m_frameTime;
    }
    else {
        m_fps = 100000.0f;
    }

    if (m_frameTime > 0.0f)
    {
       update(m_frameTime);
    }
}

void MainWidget::deleteScreen(int scr)
{
    switch(scr)
    {
        case 1:
            delete rootObject()->findChild<QObject*>("mainmenu");
            break;
        case 2:
            delete rootObject()->findChild<QObject*>("menuview");
            break;
        case 3:
            delete rootObject()->findChild<QObject*>("instructionview");
            break;
        case 4:
            delete rootObject()->findChild<QObject*>("gameview");
            break;

    }

    isHideScreen = false;
}

void MainWidget::setSoundMute(bool isMute)
{

    isSoundMute=isMute;
}

bool MainWidget::getSoundMute()
{
    return isSoundMute;
}
void MainWidget::setMusicMute(bool isMute)
{

    isMusicMute=isMute;
}

bool MainWidget::getMusicMute()
{
    return isMusicMute;
}

MainWidget::~MainWidget()
{
}

void MainWidget::minimizeWindow()
{
#if defined(Q_WS_MAEMO_5)
    // This is needed for Maemo5 to recognize minimization
    QDBusConnection connection = QDBusConnection::sessionBus();
    QDBusMessage message = QDBusMessage::createSignal("/","com.nokia.hildon_desktop","exit_app_view");
    connection.send(message);
#else
    setWindowState(Qt::WindowMinimized);
#endif
}

void MainWidget::exitApplication()
{
    QApplication::quit();
}
